/*
 * commons is a based project implemented
 * Copyright (C) 2024 Jasmine
 */
package com.easy.log.domain;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.util.CollectionUtils;

import com.easy.ip.utils.IpUtil;
import com.easy.log.enums.Include;

import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;

/**
 * 请求信息
 *
 * @author Jasmine
 * @since 1.0.0
 */
public class LogRequest {

    /** 请求方法(eg:com.cloud.upms.controller.SysMenuController.add()) */
    private String method;
    /** 请求方式(POST/GET/**) */
    private String requestMethod;
    /**
     * 请求 URL
     */
    private URI url;

    /**
     * IP
     */
    private String ip;

    /**
     * 请求头
     */
    private Map<String, String> headers;

    /** 请求参数 */
    private String params;

    /**
     * IP 归属地
     */
    private String address;

    /** 用户代理 ,客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等 */
    private String userAgent;

    /**
     * 操作系统
     */
    private String os;
    /**
     * 浏览器
     */
    private String browser;

    public LogRequest(RecordableHttpRequest request, Set<Include> includes) {
        this.requestMethod = request.getMethod();
        this.url = request.getUrl();
        this.ip = request.getIp();
        this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? request.getHeaders() : null;
        this.params = (includes.contains(Include.REQUEST_PARAMS)) ? request.getParams() : null;
        this.address = (includes.contains(Include.IP_ADDRESS)) ? IpUtil.getAddress(this.ip) : null;

        if (!CollectionUtils.isEmpty(headers)) {
            String userAgentString = this.headers.get(HttpHeaders.USER_AGENT);
            if (StringUtils.isBlank(userAgentString)) {
                userAgentString = this.headers.get(HttpHeaders.USER_AGENT.toLowerCase());
            }
            if (StringUtils.isNotBlank(userAgentString) && includes.contains(Include.USER_AGENT)) {
                // 解析agent字符串
                UserAgent userAgent = UserAgent.parseUserAgentString(userAgentString);
                // 获取操作系统对象
                OperatingSystem operatingSystem = userAgent.getOperatingSystem();
                // 获取浏览器对象
                Browser browser = userAgent.getBrowser();

                this.userAgent = userAgentString;
                this.os = operatingSystem.getName();
                this.browser = browser.getGroup().getName() + ":" + userAgent.getBrowserVersion();
            }
        }
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public URI getUrl() {
        return url;
    }

    public void setUrl(URI url) {
        this.url = url;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBrowser() {
        return browser;
    }

    public void setBrowser(String browser) {
        this.browser = browser;
    }

    public String getOs() {
        return os;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public String getUserAgent() {
        return userAgent;
    }

    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    public String getParams() {
        return params;
    }

    public void setParams(String params) {
        this.params = params;
    }
}